package com.xuecheng.content.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.api.content.model.dto.CoursePubDTO;
import com.xuecheng.api.content.model.dto.TeachplanDTO;
import com.xuecheng.common.enums.content.CourseAuditEnum;
import com.xuecheng.common.enums.content.CourseModeEnum;
import com.xuecheng.common.exception.ExceptionCast;
import com.xuecheng.content.common.constant.ContentErrorCode;
import com.xuecheng.content.common.util.QiniuUtils;
import com.xuecheng.content.convert.CoursePubConvert;
import com.xuecheng.content.entity.CourseBase;
import com.xuecheng.content.entity.CourseMarket;
import com.xuecheng.content.entity.CoursePub;
import com.xuecheng.content.mapper.CoursePubMapper;
import com.xuecheng.content.service.CourseBaseService;
import com.xuecheng.content.service.CoursePubService;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 课程发布 服务实现类
 * </p>
 *
 * @author itcast
 */
@Slf4j
@Service
public class CoursePubServiceImpl extends ServiceImpl<CoursePubMapper, CoursePub> implements CoursePubService {

    @Autowired
    private CourseBaseService courseBaseService;

    @Autowired
    private Configuration configuration;

    @Value("${file.qiniu.secretKey}")
    private String secretKey;
    @Value("${file.qiniu.accessKey}")
    private String accessKey;
    @Value("${file.qiniu.bucket}")
    private String bucket;
    @Value("${course.publish.position}")
    private String position;

    /**
     * <p>
     * 课程发布后生产静态页面上传到七牛云服务器 ，可cdn加速访问
     * </p>
     *
     * @param courseId 课程id
     * @return void
     */
    @Override
    @Transactional
    public void publishPage(Long courseId) {

        try {
            LambdaQueryWrapper<CoursePub> queryWrapper = Wrappers.lambdaQuery(CoursePub.class)
                    .eq(CoursePub::getCourseId, courseId);
            //判断课程发布数据是否存在
            CoursePub coursePub = this.getOne(queryWrapper);
            if (ObjectUtils.isEmpty(coursePub)) {
                ExceptionCast.cast(ContentErrorCode.E_120203);
            }
            CoursePubDTO coursePubDTO = CoursePubConvert.INSTANCE.entity2dto(coursePub);
            //判断课程信息审核状态是否为已发布
            CourseBase courseBase = courseBaseService.getById(courseId);
            if (!ObjectUtils.nullSafeEquals(courseBase.getAuditStatus(), CourseAuditEnum.AUDIT_PUBLISHED_STATUS.getCode())) {
                ExceptionCast.cast(ContentErrorCode.E_120201);
            }
            if (!(coursePub.getIsPub() == 1)) {
                ExceptionCast.cast(ContentErrorCode.E_120201);
            }

            //pubStatus为1的时候才生成发布信息静态页面
            Map<String, Object> dataMap = generateDataMap(coursePubDTO);
            // 3.获得页面模板
            Template template = configuration.getTemplate("learing_article.ftl");
            String templateStr = FreeMarkerTemplateUtils.processTemplateIntoString(template, dataMap);

            //freemarker生成静态页面,
            String fileKey = position + coursePub.getId() + ".html";
            QiniuUtils.upload2Qiniu(accessKey, secretKey, bucket, templateStr, fileKey);
            //发布成功修改coursePub状态,是1才修改为0(已发布)
            LambdaUpdateWrapper<CoursePub> updateWrapper = Wrappers.lambdaUpdate(CoursePub.class).eq(CoursePub::getId, coursePub.getId())
                    .set(CoursePub::getIsPub, 0)
                    .set(CoursePub::getChangeDate, LocalDateTime.now());
            boolean update = this.update(updateWrapper);
            if (!update) {
                ExceptionCast.cast(ContentErrorCode.E_120205);
            }
            //发布成功后发送事务消息，通知
        } catch (Exception e) {
            log.error("课程发布失败，课程id为：{}", courseId, e);
            ExceptionCast.cast(ContentErrorCode.E_120204);
        }
    }

    private Map<String, Object> generateDataMap(CoursePubDTO coursePub) {
        Map<String, Object> map = new HashMap<>();

        map.put("coursePub", coursePub);
        String market = coursePub.getMarket();
        CourseMarket courseMarket = JSON.parseObject(market, CourseMarket.class);
        map.put("courseMarket", courseMarket);
        String teachplan = coursePub.getTeachplan();
        TeachplanDTO teachplanNode = JSON.parseObject(teachplan, TeachplanDTO.class);
        map.put("courseTeachModeEnums", CourseModeEnum.values());
        map.put("teachplanNode", teachplanNode);

        return map;
    }
}
